/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package beans.custom;

import beans.ejb.FantasyleagueFacade;
import beans.ejb.FantasymatchFacade;
import beans.ejb.FantasyrosterperweekFacade;
import beans.ejb.FantasyteamFacade;
import beans.ejb.NflplayergameFacade;
import beans.ejb.WeekFacade;
import entities.Fantasyleague;
import entities.Fantasymatch;
import entities.Fantasyrosterperweek;
import entities.Fantasyteam;
import entities.Nflplayergame;
import entities.Week;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import tool.WeekConverter;

/**
 *
 * @author The Lunatics
 */
@ManagedBean(eager = true, name="gameController")
@ApplicationScoped
@Stateless
public class GameController {

    @EJB
    private WeekFacade weekFacade;
    @EJB
    private FantasyleagueFacade fantasyleagueFacade;
    @EJB
    private FantasyteamFacade fantasyteamFacade;
    @EJB
    private FantasymatchFacade fantasymatchFacade;
    @EJB
    private FantasyrosterperweekFacade rosterperweekFacade;
    @EJB
    private NflplayergameFacade playergameFacade;
    private String yearStr;
    private String weekStr;
    private Week currentWeek;
    private Integer currentWeekInt;

    public Integer getCurrentWeekInt() {
//        return currentWeekInt;
        currentWeekInt = getLatestWeek().getWeek();
        return currentWeekInt;
    }

    public void setCurrentWeekInt(Integer currentWeekInt) {
        this.currentWeekInt = currentWeekInt;
    }

    public Week getCurrentWeek() {
        currentWeek = getLatestWeek();
        return currentWeek;
    }

    public void setCurrentWeek(Week currentWeek) {
        this.currentWeek = currentWeek;
    }

    public String getYearStr() {
        return yearStr;
    }

    public void setYearStr(String yearStr) {
        this.yearStr = yearStr;
    }

    public String getWeekStr() {
        return weekStr;
    }

    public void setWeekStr(String weekStr) {
        this.weekStr = weekStr;
    }
    private Integer weekId;

    public Integer getWeekId() {
        return weekId;
    }

    public void setWeekId(Integer weekId) {
        this.weekId = weekId;
    }

    /**
     * Creates a new instance of GameController
     */
    public GameController() {
        System.err.println("GameController Construction");
    }

    public Week getLatestWeek() {
        List<Week> weeks = weekFacade.findAll();
        Week nextWeek = null;
        for (ListIterator<Week> it = weeks.listIterator(weeks.size()); it.hasPrevious();) {
            Week week = it.previous();
            if (week.getPassed() != 0 && nextWeek != null) {
                return nextWeek;
            } else if (week.getPassed() != 0 && nextWeek == null) {
                return null;
            }
            nextWeek = week;
        }
        // no week is passed. return the first week.
        Week week = weeks.get(0);
        return week;
    }

    public Week getLatestWeekAndSet() {
        Week week = getLatestWeek();
        week.setPassed(1);
        weekFacade.edit(week);
        return week;
    }

    public void processScores() {
//        Week week = weekFacade.getWeek(this.yearStr, this.weekStr);
        Week week = getLatestWeekAndSet();
        List<Fantasyleague> leagues = fantasyleagueFacade.findAll();
        System.err.println("Fantasy Match of Week:" + week);
        for (Iterator<Fantasyleague> it = leagues.iterator(); it.hasNext();) {
            Fantasyleague league = it.next();
            processScores(league, week);
        }
        System.err.println("Process ends");
    }

    public void processScores(Fantasyleague league, Week week) {
        System.err.println("Fantasy Match of League:" + league.getId());
        List<Fantasymatch> matches = fantasymatchFacade.find(league, week);
        for (Iterator<Fantasymatch> it = matches.iterator(); it.hasNext();) {
            Fantasymatch match = it.next();
            processScores(match);
        }
    }

    public void processScores(Fantasymatch match) {
        processScores(match.getWeekId(), match.getLeagueId(), match.getHomeTeamId(), match.getAwayTeamId());
    }

    public void processScores(Week week, Fantasyleague league, Fantasyteam homeTeam, Fantasyteam awayTeam) {
        List<Fantasyrosterperweek> homeRosters = rosterperweekFacade.findByTeamByWeek(homeTeam, week);
        List<Fantasyrosterperweek> awayRosters = rosterperweekFacade.findByTeamByWeek(awayTeam, week);

        float homeScore = getActiveScore(homeRosters, week);
        float awayScore = getActiveScore(awayRosters, week);

        Fantasymatch match = fantasymatchFacade.find(league, week, homeTeam, awayTeam);
        match.setAwayScore(awayScore);
        match.setHomeScore(homeScore);
        fantasymatchFacade.edit(match);
        System.err.println("Fantasy Match Result : " + match);

        if (homeScore > awayScore) {
            homeTeam.setCurrentWin(homeTeam.getCurrentWin() + 1);
            awayTeam.setCurrentLose(awayTeam.getCurrentLose() + 1);
        } else if (homeScore < awayScore) {
            awayTeam.setCurrentWin(awayTeam.getCurrentWin() + 1);
            homeTeam.setCurrentLose(homeTeam.getCurrentLose() + 1);
        } else if (homeScore == awayScore) {
            homeTeam.setCurrentWithdraw(homeTeam.getCurrentWithdraw() + 1);
            awayTeam.setCurrentWithdraw(awayTeam.getCurrentWithdraw() + 1);
        }
        fantasyteamFacade.edit(homeTeam);
        fantasyteamFacade.edit(awayTeam);
        processRostersNextWeek(homeRosters);
        processRostersNextWeek(awayRosters);
    }

    private float getActiveScore(List<Fantasyrosterperweek> rosters, Week week) {
        float activeScore = 0;
        for (Iterator<Fantasyrosterperweek> it = rosters.iterator(); it.hasNext();) {
            Fantasyrosterperweek roster = it.next();
            Nflplayergame playerGame = playergameFacade.findByPlayerByWeek(roster.getPlayerId(), week);
            if (roster.getFantasyPositionInRoster().contains("_") && playerGame != null) {
                System.err.println("Player Score:" + playerGame.getPlayerId() + "," + playerGame.getFantasyPosition() + "," + playerGame.getFantasyPoints());
                activeScore += playerGame.getFantasyPoints();
            }
        }
        return activeScore;
    }

    private void processRostersNextWeek(List<Fantasyrosterperweek> rosters) {
        System.err.println("processRostersNextWeek:" + rosters);
        for (Iterator<Fantasyrosterperweek> it = rosters.iterator(); it.hasNext();) {
            Fantasyrosterperweek roster = it.next();
            Week week = roster.getWeekId();
            Week nextWeek = weekFacade.getNextWeek(String.valueOf(week.getYear()), WeekConverter.getWeekString(week.getWeek()));
            if (nextWeek == null) {
                System.err.println("Week ends!");
            }
            roster.setWeekId(nextWeek);
            rosterperweekFacade.create(roster);
        }
    }

    void dispose() {
    }
}
